/*
 * $Author: isan.wong@gmail.com $
 * $Date: 2011-07-29 01:03:06 +0000 (Fri, 29 Jul 2011) $
 * $Rev: 13 $
 * $URL: http://capitalbio-smd.googlecode.com/svn/src/com/capitalbio/smd/gui/SampleListPane.java $
 */

package com.capitalbio.smd.gui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.util.Vector;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumn;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.capitalbio.smd.base.Project;
import com.capitalbio.smd.base.Sample;
import com.capitalbio.smd.base.Util;


public class SampleListPane extends JPanel {
	private static final long serialVersionUID = 1L;
	protected Log log = LogFactory.getLog(this.getClass());
	
	private ProjectPane projectPane;
	private JTable sampleListTable;
	private SampleListTableData sampleListData;
	private AdPane adPane;
	private Project project;

	public SampleListPane(ProjectPane projectPane) {
		this.projectPane = projectPane;
		UIManager.put("Table.focusCellHighlightBorder", new LineBorder(Color.black, 0));
		setLayout(new BorderLayout());
		
		initializeTable();
		JScrollPane sampleListScrollPane = new JScrollPane(sampleListTable);
		sampleListScrollPane.setBorder(new EmptyBorder(0, 0, 0, 0));
		add(sampleListScrollPane, BorderLayout.CENTER);
		
		if (Boolean.parseBoolean(Util.getProperties().getProperty("smd.gui.ad.enabled"))) {
			adPane = new AdPane();
			add(adPane, BorderLayout.SOUTH);
		}
	}
	
	public void updateProject(Project project) {
		this.project = project;
		//fireTableDataChanged();
		sampleListData.updateProject(project);
	}
	
	public ProjectPane getProjectPane() {
		return projectPane;
	}

	public void initializeTable() {

		sampleListData = new SampleListTableData(this);
		sampleListTable = new JTable();
		sampleListTable.setBorder(new EmptyBorder(0, 0, 0, 0));

		sampleListTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		sampleListTable.setRowHeight(20);
		sampleListTable.setAutoCreateColumnsFromModel(false);

		sampleListTable.setModel(sampleListData);

		for (int k = 0; k < sampleListData.getColumnCount(); k++) {
			DefaultTableCellRenderer renderer = new DefaultTableCellRenderer();
			renderer.setHorizontalAlignment(SampleListTableData.columns[k].alignment);
			TableColumn column = new TableColumn(k,
					SampleListTableData.columns[k].width, renderer, null);
			sampleListTable.addColumn(column);
		}
	}

	public JTable getSampleListTable() {
		return sampleListTable;
	}

	public void setSampleListTable(JTable sampleListTable) {
		this.sampleListTable = sampleListTable;
	}

	public SampleListTableData getSampleListData() {
		return sampleListData;
	}

	public void setSampleListData(SampleListTableData sampleListData) {
		this.sampleListData = sampleListData;
	}
}

class ColumnData {
	public String title;
	public int width;
	public int alignment;

	public ColumnData(String title, int width, int alignment) {
		this.title = title;
		this.width = width;
		this.alignment = alignment;
	}
}

class SampleListTableData extends AbstractTableModel {

	private static final long serialVersionUID = 1L;
	protected static Log log = LogFactory.getLog(SampleListTableData.class);

	private static final int COL_ID = 0;
	private static final int COL_SAMPLENAME = 1;
	private static final int COL_SAMPLESTATUS = 2;

	static final public ColumnData columns[] = {
			new ColumnData("#", 35, JLabel.LEFT),
			new ColumnData("Sample", 165, JLabel.LEFT)//,
			//new ColumnData("Status", 35, JLabel.LEFT),
		};

	protected Project project;
	SampleListPane sampleListPane;

	public SampleListTableData(SampleListPane sampleListPane) {
		this.sampleListPane = sampleListPane;
	}
	
	public void updateProject(Project project) {
		this.project = project;
		//fireTableDataChanged();
	}

	public int getRowCount() {
		return project == null ? 0 : (project.getSamples() == null ? 0 : project.getSamples().size());
	}

	public int getColumnCount() {
		return columns.length;
	}

	public String getColumnName(int column) {
		return columns[column].title;
	}

	public boolean isCellEditable(int nRow, int nCol) {
		return false;
	}

	/**
	 * 
	 * @param nRow
	 * @return
	 */
	public Sample getSampleAt(int nRow) {
		return project.getSamples().get(nRow);
	}

	public Object getValueAt(int nRow, int nCol) {
		if (nRow < 0 || nRow >= getRowCount())
			return "";
		Sample sample = project.getSamples().get(nRow);
		switch (nCol) {
		case 0:
			return nRow + 1;
		case 1:
			return sample.getName();
		case 2:
			return sample.getStatus();
		}
		return "";
	}

	public void setValueAt(Object value, int nRow, int nCol) {
		if (nRow < 0 || nRow >= getRowCount() || value == null) {
			return;
		}
		Sample sample = project.getSamples().get(nRow);

		switch (nCol) {
		case COL_ID:
			break;
		case COL_SAMPLENAME:
			sample.setName((String) value);
			break;
		case COL_SAMPLESTATUS:
			sample.setStatus((Integer) value);
			break;
		}
	}

	public void add(Sample sample) {
		project.getSamples().add(sample);
	}
	
	public boolean remove(int nRow) {
		log.debug("Removing sample index: " + nRow);
		if (nRow < 0 || nRow >= project.getSamples().size()) {
			log.debug("Removing failed.");
			return false;
		}
		Sample sample = project.removeSample(nRow);
		
		if (sample != null) {
			final int row = nRow;
			SwingUtilities.invokeLater(new Runnable() {
				public void run() {
					fireTableRowsDeleted(row, row);
				}
			});
			
			log.debug("Sample " + sample.getName()  + " removed, " + project.getSamples().size() + " samples remain.");
			return true;
		}
		
		log.debug("Removing failed.");
		return false;
	}
	
	public boolean removeIndexes(int[] nRows) {
		boolean success = true;
		for (int nRow : nRows) {
			if (!remove(nRow)) {
				success = false;
			}
		}

		return success;
	}
	
	public boolean removeAll() {
		int rowCount = getRowCount();
		project.removeAllSamples();
		log.debug((project.getSamples() == null ? "0" : project.getSamples().size()) + " samples remain.");
		
		final int rows = rowCount;
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				fireTableRowsDeleted(0, rows - 1);
			}
		});
		
		return true;
	}
}
